#include "../Shared/diplomacyclient.h"
#include "map.h"
#include "player.h"

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

SCommManager CommManager;
SMap * world;
SPlayer * self;

SInfoClient* GetInfoClient() {
	SInfoClient * info = (SInfoClient*) malloc(sizeof(SInfoClient));

	strcpy(info->NameStrategy,"BR Strategy");
	strcpy(info->NameAuthor,"Bury - Rouillé");
	info->Version[0]=0;
	info->Version[1]=0;
	info->Version[2]=0;
	info->Version[3]=1;

	return(info);
}

void ReleaseInfoClient(SInfoClient * info) {
	// Liberer la mémoire
	free(info);
	free_player(self);
	free_map(world);
}


/*
 * Fonction appelée au début de la partie par le mannager.
 * - idTeam : identifiant attribué au joueur
 * - nbTeam : nombre d'équipes dans la partie
 * - nbCell : nombre de cellules (régions) sur la carte
 */
void Initialize(unsigned int idTeam, unsigned int nbTeam, unsigned int nbCell) {
	// Interrogation possible du contenu d'une cellule et de la nature de son voisinage
	
	world = init_map(&CommManager, nbCell);
	//print_map(map);
	
	self = init_player(world, idTeam);
	//print_player(self);
}

void GetAlliances(unsigned int nbTeam) {
	// Interrogation possible du contenu d'une cellule et de la nature de son voisinage
	
	printf("Client : GetAlliances ; nbTeam(%d)\n",nbTeam);
	
	// Mise a jour de la carte
	update_map(&CommManager, world);
	
	int team[world->size];
	int cell[world->size];
	int nbAlliance = compute_alliances(world, team, cell);

	for (int i = 0; i < nbAlliance; i++) {
		CommManager.AskAlliance(team[i], cell[i]);
	}
}

void GetActions(const SAlliance ** const alliances, unsigned int nbUnit) {
	// Interrogation possible du contenu d'une cellule et de la nature de son voisinage

	UActionParam param;
	printf("Client : GetActions ; nbUnit(%u)\n",nbUnit);
	for(int i = 0; alliances[i]; i++) {
		printf("Client: Request alliance ; idTeam(%d) - idCell(%d)\n", alliances[i]->idTeam, alliances[i]->idCell);
		
		// On parcoure nos unités
		for (int j = 0; j < v_count(self->units); j++) {
			STroup u = v_get(self->units, j);
			STerritory t = world->map[u.idCell - 1];
			
			// Si le territoire concerné par la demande de support est adjacent à l'une de nos unités, on accepte.
			for (int k = 0; k < t.count_adjacent; k++) {
				if (t.adjacent[k] == alliances[i]->idCell) {
					param.ActionSupport.idTeam = alliances[i]->idTeam;
					param.ActionSupport.idCell = alliances[i]->idCell;
					CommManager.SendAction(j+1 ,ACT_Support ,param);
					break;
				}
			}
		}
	}
		
	/*
	UActionParam param;

	param.ActionMove.idCell = 34;
	CommManager.SendAction(2,ACT_Move,param);

	param.ActionSupport.idTeam = 3;
	param.ActionSupport.idCell = 12;
	CommManager.SendAction(1,ACT_Support,param);

	param.ActionTransport.idCellSource = 4;
	param.ActionTransport.idCellDestination = 14;
	CommManager.SendAction(3,ACT_Transport,param);
	 */
}

void AddUnit(unsigned int nb, SUnit * unit) {
	// Interrogation possible du contenu d'une cellule et de la nature de son voisinage

	for (int i = 0; i < nb; i++) {
		// Placer l'unité
		unit[i].idCell = getEmptyCentre(world, self->idTeam);
		unit[i].type = UT_Army;
		// Mettre la carte et le joueur a jour
		pAddUnit(self, world, unit[i]);
	}
}

void RemoveUnit(unsigned int nb, unsigned int * idUnit) {
	// Interrogation possible du contenu d'une cellule et de la nature de son voisinage

	unsigned int i;
	printf("RemoveUnit\n");
	for (i = 0;i < nb;i++)
		printf("%d\n", idUnit[i]);
}
